#include "ViewportOpenGLES.h"

namespace YoghurtGum
{

	ViewportOpenGLES::ViewportOpenGLES(uint32 a_Width, uint32 a_Height, uint32 a_Type /*= YG_VIEWPORT_DEFAULT*/) : Viewport(a_Width, a_Height, a_Type)
	{
		uint32 device_w = (uint32)Device::Get().GetWidth();
		uint32 device_h = (uint32)Device::Get().GetHeight();

		if (a_Type & YG_VIEWPORT_SCALEX)
		{
			Log::GetSingleton().Print("Viewport: ScaleX");

			m_Width = device_w;

			real ratio = (real)m_Width / (real)a_Width;
			m_Height = (int32)((real)a_Height * ratio);

			m_FixedWidth = GlUintToFixed(m_Width);
			m_FixedHeight = GlUintToFixed(m_Height);
		}
		else if (a_Type & YG_VIEWPORT_SCALEY)
		{
			Log::GetSingleton().Print("Viewport: ScaleY");
		}
		else if (a_Type & YG_VIEWPORT_SCALEXY)
		{
			Log::GetSingleton().Print("Viewport: ScaleXY");
		}
		else
		{
			m_Width = a_Width;
			m_Height = a_Height;

			m_FixedWidth = GlIntToFixed(m_Width);
			m_FixedHeight = GlIntToFixed(m_Height);
		}

		if (a_Type & YG_VIEWPORT_TOPLEFT)
		{
			m_ScissorStartX = 0;
			m_ScissorStartY = device_h - m_Height;
			m_ScissorEndX = m_Width;
			m_ScissorEndY = m_Height;
		}
		else if (a_Type & YG_VIEWPORT_TOPRIGHT)
		{
			m_ScissorStartX = device_w - m_Width;
			m_ScissorStartY = device_h - m_Height;
			m_ScissorEndX = m_Width;
			m_ScissorEndY = m_Height;
		}
		else if (a_Type & YG_VIEWPORT_BOTTOMLEFT)
		{
			m_ScissorStartX = 0;
			m_ScissorStartY = 0;
			m_ScissorEndX = m_Width;
			m_ScissorEndY = m_Height;
		}
		else if (a_Type & YG_VIEWPORT_BOTTOMRIGHT)
		{
			m_ScissorStartX = device_w - m_Width;
			m_ScissorStartY = 0;
			m_ScissorEndX = m_Width;
			m_ScissorEndY = m_Height;
		}
		else // YG_VIEWPORT_CENTER
		{
			m_ScissorStartX = (device_w - m_Width) / 2;
			m_ScissorStartY = (device_h - m_Height) / 2;
			m_ScissorEndX = m_Width;
			m_ScissorEndY = m_Height;
		}

		m_Viewport = false;
		if (a_Type & YG_VIEWPORT_VIEWPORT)
		{
			SetWorldDimensions(device_w, device_h);
			m_Viewport = true;
		}

		Log::GetSingleton().Print("Viewport dimensions: (%i x %i)", m_Width, m_Height);
		Log::GetSingleton().Print("Viewport region: (%i, %i)(%i, %i)", 
			m_ScissorStartX, m_ScissorStartY,
			m_ScissorEndX, m_ScissorEndY
		);

		m_ZNear = GlIntToFixed(-1);
		m_ZFar = GlIntToFixed(1);

		m_Pos.Clear();
	}

	ViewportOpenGLES::~ViewportOpenGLES()
	{

	}

	void ViewportOpenGLES::Resize(uint32 a_Width, uint32 a_Height)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetType(uint32 a_Type)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetBounds(Vec2 a_Dim)
	{
		m_Offset = a_Dim;
	}

	Vec2 ViewportOpenGLES::GetScreenPosition(Vec2 a_WorldPos)
	{
		YG_STUB;
		return Vec2(0, 0);

		/*if (m_Viewport)
		{
			Vec2 result = a_WorldPos - m_Pos;
			while (result.x > (real)m_Width)
			{
				result.x -= (real)m_Width;
			}
			while (result.y > (real)m_Height)
			{
				result.y -= (real)m_Height;
			}

			//Log::GetSingleton().Print("Viewport in: (%f, %f) out: (%f, %f)", 
			//	a_WorldPos.x, a_WorldPos.y,
			//	result.x, result.y
			//);

			return result;
		}
		else
		{
			//Log::GetSingleton().Print("Viewport in: (%f, %f) out: (%f, %f)", 
			//	a_WorldPos.x, a_WorldPos.y,
			//	a_WorldPos.x, a_WorldPos.y
			//);
			return a_WorldPos;
		}*/
	}

	Vec2 ViewportOpenGLES::GetCenterPosition(Vec2 a_WorldPos)
	{
		YG_STUB;
		return Vec2(0, 0);
	}

	void ViewportOpenGLES::SetX(real32 a_X)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetY(real32 a_Y)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetPosition(real32 a_X, real32 a_Y)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::Move(real32 a_SpeedX, real32 a_SpeedY)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetTargetPosition(uint32 a_X, uint32 a_Y)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetDimensions(uint32 a_Width, uint32 a_Height)
	{
		YG_STUB;
	}

	void ViewportOpenGLES::SetWorldDimensions(uint32 a_Width, uint32 a_Height)
	{
		YG_STUB;
	}

	bool ViewportOpenGLES::Enable()
	{
		glEnable(GL_SCISSOR_TEST); CGLE();
		glScissor(
			m_ScissorStartX, m_ScissorStartY, 
			m_ScissorEndX, m_ScissorEndY
		); CGLE();

		Project();
	}

	bool ViewportOpenGLES::Disable()
	{
		glDisable(GL_SCISSOR_TEST);	
	}

	void ViewportOpenGLES::Project()
	{
		glViewport(
			m_ScissorStartX, m_ScissorStartY, 
			m_ScissorEndX, m_ScissorEndY
		); CGLE();

		glMatrixMode(GL_PROJECTION); CGLE();
			glLoadIdentity(); CGLE();
			glOrthox(
				0, m_FixedWidth, 
				m_FixedHeight, 0,
				m_ZNear, m_ZFar
			); CGLE();
		glMatrixMode(GL_MODELVIEW); CGLE();
			glLoadIdentity(); CGLE();
	}

}